package com.yegs.jltqc.serviceImpl;

import com.yegs.jltqc.TO.NamePageQuery;
import com.yegs.jltqc.TO.RpproducePageQuery;
import com.yegs.jltqc.U8Service.PpbarcodeService;
import com.yegs.jltqc.U8Service.U8QcProduceService;
import com.yegs.jltqc.VO.*;
import com.yegs.jltqc.common.StoreException;
import com.yegs.jltqc.config.ConcurentCache;
import com.yegs.jltqc.dao.QcProduceRepository;
import com.yegs.jltqc.dao.RpProduceBarcodeRepository;
import com.yegs.jltqc.dao.RpProduceRepository;
import com.yegs.jltqc.dao.WorkFlowRepository;
import com.yegs.jltqc.service.QcProduceService;
import com.yegs.jltqc.service.RpProduceService;
import com.yegs.jltqc.util.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class RpProduceServiceImpl implements RpProduceService {


    private final String MEASUREMENT_weijian = "未检";
    private final String MEASUREMENT_yijian = "已检";
    private final String MEASUREMENT_hege = "合格";
    private final String MEASUREMENT_tecai = "特采";
    private final String MEASUREMENT_quanjian = "全检";
    private final String MEASUREMENT_fangong = "返工";

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private RpProduceRepository rpProduceRepository;

    @Autowired
    private RpProduceBarcodeRepository rpProduceBarcodeRepository;

    @Autowired
    private U8QcProduceService u8QcProduceService;

    @Autowired
    private PpbarcodeService ppbarcodeService;


    @Override
    public RpProduce save(RpProduce rpProduce) {
        try {
            //新单
            if(rpProduce.getId() == null){
                for(RpProduceBarcode barcode : rpProduce.getBarcodes()){
                    this.checkQc(barcode.getCbarcode());
                }
                rpProduce.setCreateBy(ConcurentCache.getUserName());
                rpProduce.setCreateTime(new Date());
            }else {
                rpProduce.setUpdateBy(ConcurentCache.getUserName());
                rpProduce.setUpdateTime(new Date());

                RpProduce produce = rpProduceRepository.getOne(rpProduce.getId());
                //已检测过
                if(produce.getMeasurement() !=null){
                    rpProduce.setId(produce.getId());
                }else if("合格".equals(rpProduce.getMeasurement())||"特采".equals(rpProduce.getMeasurement())||"全检".equals(rpProduce.getMeasurement())){
                    for(RpProduceBarcode barcode : rpProduce.getBarcodes()){
                        this.checkQc(barcode.getCbarcode());
                    }
                    if("生产".equals(rpProduce.getQctype())){
                        String cwhcode = "";
                        //Integer pid = ppbarcodeService.insertymhWorkshopPprd10(cCode, null, cwhcode, rpProduce.getCreateBy());
                        List<String> barcodes = new ArrayList<>();
                        for(RpProduceBarcode barcode : rpProduce.getBarcodes()){
                            if(barcodes.contains(barcode.getCbarcode())){
                                continue;
                            }else{
                                barcodes.add(barcode.getCbarcode());
                            }
                            String cCode = ppbarcodeService.getCCode();
                            String cposcode = "";
                            ppbarcodeService.updateYmhPoqcdata(rpProduce.getMeasurement(),barcode.getCbarcode());
                            ppbarcodeService.insertQcrecode(barcode.getCbarcode(),rpProduce.getModid(),new Date(),rpProduce.getMeasurement());
                            ppbarcodeService.insertymhWorkshopPprds10(0,rpProduce.getCinvcode(),barcode.getQty(),cposcode,barcode.getCbarcode(),0L,cCode, null, cwhcode, rpProduce.getCreateBy());
                            logger.info("生产updateppbarcode"+barcode.getCbarcode(),"质检",new Date());
                            ppbarcodeService.updateppbarcode(barcode.getCbarcode(),"质检",new Date());
                        }
                    }else if("接收".equals(rpProduce.getQctype())){
                        for(RpProduceBarcode barcode : rpProduce.getBarcodes()){
                            this.checkQc(barcode.getCbarcode());
                        }
                        List<String> barcodes = new ArrayList<>();
                        for(RpProduceBarcode barcode : rpProduce.getBarcodes()){
                            if(barcodes.contains(barcode.getCbarcode())){
                                continue;
                            }else{
                                barcodes.add(barcode.getCbarcode());
                            }
                            ppbarcodeService.updateYmhPoqcdata(rpProduce.getMeasurement(),barcode.getCbarcode());
                            ppbarcodeService.insertQcrecode(barcode.getCbarcode(),rpProduce.getModid(),new Date(),rpProduce.getMeasurement());
                            logger.info("接收updateppbarcode"+barcode.getCbarcode(),"质检",new Date());
                            ppbarcodeService.updateppbarcode(barcode.getCbarcode(),"质检",new Date());
                            Integer id = ppbarcodeService.findymhWorkshopPprds10(barcode.getCbarcode());
                            logger.info("syncrdpprecord10_forqc2"+id);
                            ppbarcodeService.syncrdpprecord10_forqc2(id);
                        }
                    }
                }else if("返工".equals(rpProduce.getMeasurement())){
                    for(RpProduceBarcode barcode : rpProduce.getBarcodes()){
                        this.checkQc(barcode.getCbarcode());
                    }
                    List<String> barcodes = new ArrayList<>();
                    for(RpProduceBarcode barcode : rpProduce.getBarcodes()){
                        if(barcodes.contains(barcode.getCbarcode())){
                            continue;
                        }else{
                            barcodes.add(barcode.getCbarcode());
                        }
                        ppbarcodeService.updateYmhPoqcdata(rpProduce.getMeasurement(),barcode.getCbarcode());
                        ppbarcodeService.insertQcrecode(barcode.getCbarcode(),rpProduce.getModid(),new Date(),rpProduce.getMeasurement());
                        ppbarcodeService.updateppbarcode(barcode.getCbarcode(),"质检",null);
                    }
                }
            }
            return rpProduceRepository.save(rpProduce);
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }
    }

    @Override
    public List<RpProduce> list() {
        return rpProduceRepository.findAll();
    }

    @Override
    public RpProduce get(Long id) {
        return rpProduceRepository.getOne(id);
    }

    @Override
    public RpProduce findRpProduceByBarcode(String barcode) {
        Map<String, Object> map = ppbarcodeService.findByBarcode(barcode);
        if(map == null){
            return null;
        }
        Integer modid = (Integer) map.get("modid");
        return rpProduceRepository.findFirstByModidOrderByIdDesc(modid + 0l);
    }

    @Override
    public void del(Long id) {
        rpProduceRepository.deleteById(id);
    }

    @Override
    public Page<RpProduce> query(RpproducePageQuery query) {

        PageRequest request = PageRequest.of(query.getPageIndex() - 1, query.getPageSize(), Sort.Direction.DESC,"id");
        Specification<RpProduce> specification = new Specification<RpProduce>() {
            @Override
            public Predicate toPredicate(Root<RpProduce> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                if(query.getMocode() != null && query.getMocode().trim().length() > 0){
                    predicates.add(criteriaBuilder.like(root.get("mocode"),"%" + query.getMocode() + "%"));
                }
                if(query.getCsocode() != null && query.getCsocode().trim().length() > 0){
                    predicates.add(criteriaBuilder.like(root.get("csocode"),"%" + query.getCsocode() + "%"));
                }
                if(query.getSddate() != null){
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("ddate"),query.getSddate()));
                }
                if(query.getEddate() != null){
                    predicates.add(criteriaBuilder.lessThan(root.get("ddate"), DateUtils.addDay(query.getEddate())));
                }
                if(query.getDdate() != null){
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("ddate"),query.getDdate()));
                    predicates.add(criteriaBuilder.lessThan(root.get("ddate"), DateUtils.addDay(query.getDdate())));
                }
                if(query.getScreate() != null){
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), DateUtils.addDay(query.getScreate())));
                }
                if(query.getEcreate() != null){
                    predicates.add(criteriaBuilder.lessThan(root.get("createTime"),query.getEcreate()));
                }
                if(query.getCreate() != null){
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"),query.getCreate()));
                    predicates.add(criteriaBuilder.lessThan(root.get("createTime"), DateUtils.addDay(query.getCreate())));
                }
                if(MEASUREMENT_weijian.equals(query.getMeasurement())){
                    predicates.add(criteriaBuilder.isNull(root.get("measurement")));
                }
                if(MEASUREMENT_yijian.equals(query.getMeasurement())){
                    predicates.add(criteriaBuilder.isNotNull(root.get("measurement")));
                }
                if(MEASUREMENT_hege.equals(query.getMeasurement())||MEASUREMENT_fangong.equals(query.getMeasurement())
                        ||MEASUREMENT_quanjian.equals(query.getMeasurement())||MEASUREMENT_tecai.equals(query.getMeasurement())){
                    predicates.add(criteriaBuilder.equal(root.get("measurement"),query.getMeasurement()));
                }

                if(query.getCbarcode() != null){
                    List<RpProduceBarcode> barcodes = rpProduceBarcodeRepository.findAllByCbarcodeLikeAndRefIdIsNotNull(query.getCbarcode());
                    if(barcodes.size() > 0){
                        CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get("id"));
                        for(RpProduceBarcode barcode : barcodes){
                            in.value(barcode.getRefId());
                        }
                        predicates.add(in);
                    }
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
       return rpProduceRepository.findAll(specification, request);
    }

    @Override
    public RpProduce findRpProduceBySubBarcode(String barcode) {
        RpProduceBarcode rpb = rpProduceBarcodeRepository.findFirstByCbarcodeOrderByIdDesc(barcode);
        if(rpb == null){
            return null;
        }
        return rpProduceRepository.getOne(rpb.getRefId());
    }

    @Override
    public Long getNext(Long id) {
        if(id == null){
            RpProduce project = rpProduceRepository.findFirstByOrderByIdDesc();
            if(project != null) {
                return project.getId();
            }
        }
        RpProduce project = rpProduceRepository.findFirstByIdIsAfter(id);
        if(project == null){ project = rpProduceRepository.findFirstByOrderByIdDesc(); }
        if(project != null){
            return project.getId();
        }
        return null;
    }

    @Override
    public Long getLast(Long id) {
        if(id == null){
            RpProduce project = rpProduceRepository.findFirstByOrderByIdDesc();
            if(project != null) {
                return project.getId();
            }
        }
        else{
            RpProduce project = rpProduceRepository.findFirstByIdBeforeOrderByIdDesc(id);
            if(project == null){ project = rpProduceRepository.findFirstByOrderById(); }
            if(project != null){
                return project.getId();
            }
        }
        return null;
    }

    /**
     * 通过qctime确认是否质检过
     * @param barcode
     */
    private void checkQc(String barcode){
        Map<String, Object> map = ppbarcodeService.findByBarcode(barcode);
        if(map == null){
            throw new StoreException("托盘码不存在!");
        }
        if(map.get("qctime") != null){
            throw new StoreException(barcode+"已质检!");
        }
    }


}
